package com.example.travelservlet.user.controller;



import com.alibaba.fastjson.JSONObject;
import com.easemob.im.server.EMException;
import com.easemob.im.server.EMService;
import com.example.travelservlet.city.service.CityService;
import com.example.travelservlet.entity.City;
import com.example.travelservlet.entity.Entertainment;
import com.example.travelservlet.user.domain.UserResult;
import com.example.travelservlet.entity.User;
import com.example.travelservlet.user.domain.Result;
import com.example.travelservlet.user.repository.UserRepository;
import com.example.travelservlet.user.service.UserService;
import com.example.travelservlet.util.Number;
import com.example.travelservlet.utils.ResultUtil;
import com.example.travelservlet.utils.UserResultUtil;
import com.zhenzi.sms.ZhenziSmsClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;


import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.validation.Valid;
import java.util.*;
import java.util.Properties;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @author dell
 */
@RestController
@RequestMapping("/user")
public class UserController {

    private String CODE;
    private String apiUrl = "https://sms_developer.zhenzikj.com";
    /**
     * 榛子云系统上获取
     */

    private String appId = "112516";
    private String appSecret = "cdd20a2e-558f-4c8e-8245-382740f7736a";

    @Autowired
    private EMService emService;

    @Autowired
    private UserService userService;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private CityService cityService;


    @GetMapping("/findUserInfo")
    public ModelAndView findUserInfo(User user) {
        ModelAndView modelAndView = new ModelAndView();
        List<User> userInfoList = userService.findUserInfo(user);
        modelAndView.addObject("userInfoList", userInfoList);
        modelAndView.addObject("userInfo", user);
        modelAndView.setViewName("user/userInfoList");
        return modelAndView;
    }
    /**
     * 注册
     */
    @PostMapping("/register")
    public Result<User> register(@Valid String loginName, @Valid String password, @Valid String confirmPassword, @Valid String code){
        User user = new User();
        List<User> userList = userService.findUser();
        for (User user1 : userList){
            if (loginName.equals(user1.getLoginName())) {
                return ResultUtil.error("用户名已存在，请换一个");
            }
        }
        if (password.equals(confirmPassword)){
            user.setLoginName(loginName);
            user.setPassword(password);
            user.setUserName("U" + Number.getRandomNickName(10));
            user.setCityId("5");
            user.setSex("女");
            user.setBirthday("2022-12-24");
            if (StringUtils.isEmpty(loginName)){
                return ResultUtil.error("用户名为空，请核实");
            }
            if (!code.equals(CODE)){
                return ResultUtil.error("验证码错误");
            }
            userService.createUser(user);
            return ResultUtil.success(user);
        }else {
            return ResultUtil.error("密码和确认密码不一致");
        }
    }
    @PostMapping("/create")
    public Result<User> create(@Valid String loginName, @Valid String userName, @Valid String sex, @Valid String head,@Valid String birthday,@Valid String city,@Valid String backPicture){
        User user = new User();
        List<User> userList = userService.findUser();
        for (User user1 : userList){
            if (loginName.equals(user1.getLoginName())) {
                return ResultUtil.error("用户名已存在，请换一个");
            }
        }
        City cityByName = cityService.findCityByName(city);

        user.setLoginName(loginName);
        user.setUserName(userName);
        user.setCityId(cityByName.getCityId());
        user.setSex(sex);
        user.setBirthday(birthday);
        user.setHead(head);
        user.setBackPicture(backPicture);
        System.out.println("head"+head+"和"+backPicture);
        userService.createUser(user);
        return ResultUtil.success(user);
    }

    @PostMapping("/login")
    public Result<User> login(@Valid String loginName, @Valid String password){
        User user = userService.findUserByLoginName(loginName);
        if (StringUtils.isEmpty(loginName)){
            return ResultUtil.error("用户名为空，请核实");
        }
        if (StringUtils.isEmpty(password)){
            return ResultUtil.error("密码为空，请核实");
        }
        if (StringUtils.isEmpty(user) || user.equals("")){
            return ResultUtil.error("用户不存在");
        }else {

            if (!user.getPassword().equals(password)){
                return ResultUtil.error("密码错误");
            }else {
                return ResultUtil.success(user);
            }
        }


    }


    @PostMapping("/forgetPassword")
    public Result<User> forgetPassword(@Valid String loginName,@Valid String password, @Valid String confirmPassword, @Valid String code){
        User user = userService.findUserByLoginName(loginName);
        if (password.equals(confirmPassword)){
            if (!code.equals(CODE)){
                return ResultUtil.error("验证码错误");
            }
            user.setPassword(password);
            userService.updateUser(user);
            return ResultUtil.success(user);
        }else {
            return ResultUtil.error("密码和确认密码不一致");
        }
    }

    @PostMapping("/updateCityId")
    public Result<User> updateCityId(@Valid String cityId, @Valid String loginName) {
        User user = userService.findUserByLoginName(loginName);
        user.setCityId(cityId);
        userService.updateUser(user);
        return ResultUtil.success(user);
    }

    @PostMapping("/updateUserName")
    public Result<User> updateUserName(@Valid String userName, @Valid String loginName) {
        User user = userService.findUserByLoginName(loginName);
        user.setUserName(userName);
        userService.updateUser(user);
        return ResultUtil.success(user);
    }

    @PostMapping("/updateBirthday")
    public Result<User> updateBirthday(@Valid String birthday, @Valid String loginName) {
        User user = userService.findUserByLoginName(loginName);
        user.setBirthday(birthday);
        userService.updateUser(user);
        return ResultUtil.success(user);
    }

    @PostMapping("/updateSex")
    public Result<User> updateSex(@Valid String sex, @Valid String loginName) {
        User user = userService.findUserByLoginName(loginName);
        user.setSex(sex);
        userService.updateUser(user);
        return ResultUtil.success(user);
    }

    @PostMapping("/updateHead")
    public Result<User> updateHead(@Valid String head, @Valid String loginName) {
        User user = userService.findUserByLoginName(loginName);
        user.setHead(head);
        userService.updateUser(user);
        return ResultUtil.success(user);
    }

    @PostMapping("/updateBackPicture")
    public Result<User> updateBackPicture(@Valid String backPicture, @Valid String loginName) {
        User user = userService.findUserByLoginName(loginName);
        user.setBackPicture(backPicture);
        userService.updateUser(user);
        return ResultUtil.success(user);
    }

    @PostMapping("/update")
    public Result<User> update(@Valid String userId,@Valid String loginName, @Valid String userName, @Valid String sex, @Valid String head,@Valid String birthday,@Valid String city,@Valid String backPicture) {
        User user = new User();
        List<User> userList = userService.findUser();
        City cityByName = cityService.findCityByName(city);
        user.setUserId(userId);
        user.setLoginName(loginName);
        user.setUserName(userName);
        user.setCityId(cityByName.getCityId());
        user.setSex(sex);
        user.setBirthday(birthday);
        user.setHead(head);
        user.setBackPicture(backPicture);

        userService.updateUser(user);
        return ResultUtil.success(user);
    }


    /**
     *
     * @param
     * @return
     */
    @GetMapping("/cancelUser/{loginName}")
    public Result cancelUser(@PathVariable String loginName){
        userService.deleteByLoginName(loginName);
        //环信删除用户
        String huanxinSignUpName;
        if (loginName.indexOf("@") == -1){
            huanxinSignUpName = loginName;
        } else {
            String[] split = loginName.split("[@,\\.]");
            String join = String.join("", split);
            huanxinSignUpName = join;
        }
        try {
            emService.user().delete(huanxinSignUpName).block();
        } catch (EMException e) {
            e.getErrorCode();
            e.getMessage();
        }
        return ResultUtil.sucess("200","注销成功",null);
    }

    @GetMapping("/mailVerificationCode/{loginName}")
    public String mailVerificationCode(@PathVariable String loginName) throws MessagingException {
        //定义邮箱服务器配置
        Properties prop = new Properties();
        // 设置邮件服务器主机名（163 邮件服务器地址："mail.smtp.host"  "smtp.163.com"）
        prop.setProperty("mail.smtp.host", "ssl://smtp.163.com");
        // 设置邮件服务器的端口
        prop.setProperty("mail.transport.protocol", "smtps");
        prop.setProperty("mail.smtp.port", "465");
        prop.setProperty("spring.mail.default-encoding", "utf-8");
        prop.setProperty("spring.mail.ssl.enable","true");
        // 设置邮件服务器认证属性 （设置为true表示发送服务器需要身份验证）
        prop.setProperty("mail.smtp.auth", "true");
        prop.setProperty("mail.smtp.starttls.enable","true");
        prop.setProperty("mail.smtp.starttls.required", "true");

        // 使用JavaMail发送邮件的5个步骤
        // 1. 创建session
        Session session = Session.getInstance(prop);
        // 开启Session的debug模式，这样就可以查看到程序发送Email的运行状态
        session.setDebug(true);
        // 2. 通过session得到transport对象
        Transport ts = session.getTransport();
        // 3. 使用邮箱的用户名和密码连上邮件服务器（用户名只需写@前面的即可，密码是指授权码）
        ts.connect("smtp.163.com", "hxysmiling", "FGHZZCNJMVANPYTB");
        // 4. 创建邮件
        // 发送普通文本的邮件
        Message message = createSimpleTxtMail(session,loginName);
        // 5. 发送邮件
        ts.sendMessage(message, message.getAllRecipients());
        // 关闭transport对象
        ts.close();
        return null;
    }
    private Message createSimpleTxtMail(Session session,String loginName) throws MessagingException {
        //创建邮件对象
        MimeMessage message = new MimeMessage(session);
        // 设置邮件的发件人的邮箱地址
        message.setFrom(new InternetAddress("hxysmiling@163.com"));
        // 设置邮件的收件人的邮箱地址 （现在发件人和收件人是一样的，那就是自己给自己发）
        message.setRecipient(Message.RecipientType.TO, new InternetAddress(loginName));

        // 邮件的主题
        message.setSubject("[伴旅]验证码");
        // 设置发送日期
        message.setSentDate(new Date());
        // 邮件的文本内容 （setText()：纯文本内容）

        CODE = String.valueOf(ThreadLocalRandom.current().nextInt(100000, 1000000));
        message.setText(CODE);
        // 返回创建好的邮件对象
        return message;

    }

    @PostMapping("userThinking")
    public String userThinking(@Valid String loginName, @Valid String thinking) throws MessagingException {
        //定义邮箱服务器配置
        Properties prop = new Properties();
        // 设置邮件服务器主机名（163 邮件服务器地址："mail.smtp.host"  "smtp.163.com"）
        prop.setProperty("mail.smtp.host", "smtp.163.com");
        // 设置邮件服务器的端口
        prop.setProperty("mail.smtp.port", "25");
        // 设置邮件服务器认证属性 （设置为true表示发送服务器需要身份验证）
        prop.setProperty("mail.smtp.auth", "true");

        // 使用JavaMail发送邮件的5个步骤
        // 1. 创建session
        Session session = Session.getInstance(prop);
        // 开启Session的debug模式，这样就可以查看到程序发送Email的运行状态
        session.setDebug(true);
        // 2. 通过session得到transport对象
        Transport ts = session.getTransport();
        // 3. 使用邮箱的用户名和密码连上邮件服务器（用户名只需写@前面的即可，密码是指授权码）
        ts.connect("smtp.163.com", "hxysmiling", "FGHZZCNJMVANPYTB");
        // 4. 创建邮件
        // 发送普通文本的邮件
        Message message = createMail(session, loginName, thinking);
        // 5. 发送邮件
        ts.sendMessage(message, message.getAllRecipients());
        // 关闭transport对象
        ts.close();
        return null;
    }

    private Message createMail(Session session, String loginName, String thinking) throws MessagingException {
        //创建邮件对象
        MimeMessage message = new MimeMessage(session);
        // 设置邮件的发件人的邮箱地址
        message.setFrom(new InternetAddress("hxysmiling@163.com"));
        // 设置邮件的收件人的邮箱地址 （现在发件人和收件人是一样的，那就是自己给自己发）
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("779165750@qq.com"));

        // 邮件的主题
        message.setSubject("用户反馈信息");
        // 设置发送日期
        message.setSentDate(new Date());
        // 邮件的文本内容 （setText()：纯文本内容）
        message.setText(loginName + ":" + thinking);
        // 返回创建好的邮件对象
        return message;

    }

    @GetMapping("/phoneVerificationCode/{loginName}")
    public boolean phoneVerificationCode(@PathVariable String loginName) throws Exception {

        //短信发送需要的参数是json类型
        JSONObject json = null;
        //随机6位生成验证码
        String code =String.valueOf(ThreadLocalRandom.current().nextInt(100000, 1000000));
        //将验证码通过榛子云接口发送至手机
        ZhenziSmsClient client = new ZhenziSmsClient(apiUrl, appId, appSecret);
        //参数类型
        Map<String, Object> params = new HashMap<String, Object>();
        //前台输入的手机号
        params.put("number", loginName);
        //这个模板id对应的是榛子云个人中心的模板id
        params.put("templateId", 10636);
        //参数占位符,不同的模板有不同的参数个数 目前用的模板有两个参数
        String[] templateParams = new String[2];
        //第一个参数 随机生成的六位验证码
        templateParams[0] = code;
        //第二个参数 x分钟
        templateParams[1] = "5";
        //把参数占位符放在整体参数中
        params.put("templateParams", templateParams);
        //执行发送短信
        String result = client.send(params);
        System.out.println(result);
        json = JSONObject.parseObject(result);
        //发送短信失败
        if (json.getIntValue("code")!=0){
            return  false;
        }
        return true;

    }

    @PostMapping("findUsers")
    public Result<List<User>> findUsers() {
        List<User> users = userService.findUser();
        return ResultUtil.success(users);
    }

//    @GetMapping("/findAllUser")
//    public UserResult<List<User>> findAllUser(User user, @RequestParam(name = "page",required = false,defaultValue = "1")Integer page,
//                                              @RequestParam(name = "size",required = false,defaultValue = "10")Integer size) {
//        Pageable pageable = PageRequest.of(page-1,size);
//        Page pageRequest = userService.findAllUser(user,pageable);
//        return UserResultUtil.success(pageRequest);
//    }
    @GetMapping("/findAllUsers")
    public UserResult<List<User>> findAllUsers(@RequestParam(name = "page", required = false, defaultValue = "1") Integer page,
                                               @RequestParam(name = "size", required = false, defaultValue = "10") Integer size){
        List<User> users = userService.findAllUsers();
        Pageable pageable = PageRequest.of(page - 1, size);
        Page pageResult = userService.findAllUsers1(pageable);
        return UserResultUtil.success(pageResult,users.size());
    }

    @GetMapping("/findUsersByKey/{key}")
    public UserResult<List<User>> findUsersByKey(@RequestParam(name = "page", required = false, defaultValue = "1") Integer page,
                                                 @RequestParam(name = "size", required = false, defaultValue = "10") Integer size,@PathVariable String key){
        List<User> users = userService.findUsersByKey(key);
        Pageable pageable = PageRequest.of(page - 1, size);
        Page pageResult = userService.findUsersByKey1(key,pageable);
        return UserResultUtil.success(pageResult,users.size());
    }
    @PostMapping("/add")
    public User saveOrUpdateUser(User user){
        return userService.createUser(user);
    }


    @GetMapping("/findUserResearch/{str}")
    public UserResult<List<Entertainment>> findEntertainmentResearch(@PathVariable String str){

        List<User> research = userService.findResearch(str);

        return UserResultUtil.success(research,research.size());
    }
}